#include <string>
#include <iostream>

class Image //abstract
{
	protected:
		Image() {}
	public:
		virtual ~Image() {}
		virtual void displayImage() = 0;
};

class RealImage : public Image
{
	public:
		explicit RealImage(std::string filename) {
			this->filename = filename;
			loadImageFromDisk();
		}

		void displayImage() {
			std::cout<<"Displaying "<<filename<<std::endl;
		}

	private:
		void loadImageFromDisk() {
			// Potentially expensive operation
			std::cout<<"Loading    "<<filename<<std::endl;
		}

		std::string filename;
};

class ProxyImage : public Image
{
	public:
		explicit ProxyImage(std::string filename) {
			this->filename = filename;
			this->image = NULL;
		}
		~ProxyImage() { delete image; }

		void displayImage() {
			if (image == NULL) {
				image = new RealImage(filename); // load only on demand
			}

			image->displayImage();
		}

	private:
		std::string filename;
		Image* image;
};

int main(int argc, char* argv[])
{
	std::cout<<"main"<<std::endl;

	Image* image1 = new ProxyImage("HiRes_10MB_Photo1");
	Image* image2 = new ProxyImage("HiRes_10MB_Photo2");
	Image* image3 = new ProxyImage("HiRes_10MB_Photo3");      

	image1->displayImage(); // loading necessary
	image2->displayImage(); // loading necessary
	image1->displayImage(); // no loading necessary; already done
	// the third image will never be loaded - time saved!

	delete image1;
	delete image2;
	delete image3;

	return 0;
}

